<?php
namespace app\api\model;

use think\Model;
use think\Db;
use think\Session;

/**
 * www.zhouchunyu.com.
 * Created on 2019/1/7 17:22
 * Created by One <admin@zhouchunyu.com>
 */

class Folder extends Model {

    public $UID;

    public function __construct($uid = 0)
    {
        parent::__construct();
        $this->UID = $uid;
    }

    /**
     * 递归创建目录
     * @param string $folder
     * @param int $pdir_id
     * @param string $pdir_name
     * @return bool|mixed
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function createFolder($folder='/', $pdir_id=0, $pdir_name='/') {
        if($folder == '' || $this->UID == 0) {
            error('Illegal request', 403);
        }
        $folder = ltrim($folder,'/');
        $dirArr = explode('/',$folder);
        foreach ($dirArr as $k => $item) {
            if($item == '' || $item == '/') {
                unset($dirArr[$k]);
            }
        }
        $dir_name = count($dirArr) == 0 ? '/' : $dirArr[0];
        $pdir_id = count($dirArr) == 0 ? 0 : $pdir_id;
        $dir = Db::name('dirs')->where('uid', $this->UID)->where('dir_name',$dir_name)->where('pdir_id',$pdir_id)->find();

        if($pdir_id != 0) { // 判断上级目录是否存在
            $pdirInfo = Db::name('dirs')->where('uid',$this->UID)->where('id',$pdir_id)->find();
            if(!$pdirInfo){
                error('上级目录不存在',412);
            }
            $pdir_name = $pdirInfo['pdir_name'];
        } else { // 顶级目录是否存在
            $TopDir = Db::name('dirs')->where('uid',$this->UID)->where('pdir_id',0)->find();
            if($TopDir) {
                error('非法目录路径',412);
            }
        }
        if(!$dir){

            if(Session::get('client_ip') == null) {
                Session::set('client_ip', getIp());
            }
            $clientIp = Session::get('client_ip');
            $time = time();
            $ppdir_id = 0;
            if($pdir_id != 0) {
                $pDirInfo = Db::name('dirs')->where('uid', $this->UID)->where('id',$pdir_id)->find();
                $pdir_name = $pDirInfo['dir_name'];
                $ppdir_id = $pDirInfo['ppdir_id'];
            }
            $InsertData = [
                'uid' => $this->UID,
                'dir_name' => $dir_name == '' ? '/' : $dir_name,
                'dir_ctime' => $time,
                'dir_mtime' => $time,
                'client_ipaddr' => $clientIp,
                'pdir_id' => $pdir_id,
                'pdir_name' => $pdir_name,
                'ppdir_id' => $ppdir_id,
                'dirid' => create_guid()
            ];

            if(Db::name('dirs')->insert($InsertData)) {
                $dir_id = Db::name('dirs')->getLastInsID();
                Db::name('dirs')->where('id', $dir_id)->update(['ppdir_id'=>$ppdir_id.','.$dir_id]);
                Db::name('dirs')->where('id', 'in', $ppdir_id)->setInc('total_dir_cnt');
                unset($dirArr[0]);
                if(count($dirArr) >= 1) {
                    return $this->createFolder(implode('/', $dirArr), $dir_id);
                } else {
                    return $dir_id;
                }
            } else {
                error('文件夹创建失败', 500);
            }
        } else {
            unset($dirArr[0]);
            if(count($dirArr) > 1) {
                return $this->createFolder(implode('/', $dirArr), $dir['id']);
            } else {
                return $dir['id'];
            }
        }
    }

    /**
     * 根据文件夹ID删除文件夹
     * @param array $folder_ids
     * @return array|int
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function delete($folder_ids=[]) {
        if($folder_ids == []) {
            error('没有选择删除的文件夹',406);
        }
        $ret = [];
        foreach ($folder_ids as $fid) {
            $status = 0;
            $dir = Db::name('dirs')->where('uid', $this->UID)->where('id', $fid)->find();
            if(!$dir) {
                $status = 0;
            } else {
                if($dir['pdir_id'] == 0) {
                    $status = 0;
                }

                $isDel = Db::name('dirs')->where('id', $dir['id'])->update(['is_del'=>1, 'del_time'=>time(), 'dir_mtime'=>time()]);
                if ($isDel !== false) {
                    $count = Db::name('dirs')->where('ppdir_id', 'in', $dir['ppdir_id'])->count();
                    // 所有父级减去文件夹数量
                    Db::name('dirs')
                        ->where('id', 'in', str_replace(','.$dir['id'],'',$dir['ppdir_id']))
                        ->setDec('total_dir_cnt', $count);
                    // 所有父级减去文件数量
                    Db::name('dirs')
                        ->where('id', 'in', str_replace(','.$dir['id'],'',$dir['ppdir_id']))
                        ->setDec('total_file_cnt', $dir['total_file_cnt']);

                    // 所有父级减去文件大小
                    Db::name('dirs')
                        ->where('id', 'in', str_replace(','.$dir['id'],'',$dir['ppdir_id']))
                        ->setDec('total_file_size', $dir['total_file_size']);
                    $status = 1;
                }else{
                    $status = 0;
                }
            }

            $ret[] = [
                'id' => $fid,
                'status' => $status,
            ];
        }

        return $ret;
    }

    /**
     * 从回收站恢复文件夹
     * @param array $folder_ids
     */
    public function recovery($folder_ids=[]) {

    }

    /**
     * 从回收站删除文件
     * @param array $folder_ids
     */
    public function clear($folder_ids=[]) {

    }

    /**
     * 复制文件夹到指定目录
     * @param $folder_ids
     */
    public function copy($folder_ids=[], $Toid=0) {
        // 判断容量时候足够
    }

    /**
     * 移动文件夹到指定目录
     * @param array $folder_ids
     * @param int $Toid
     */
    public function move($folder_ids=[], $Toid=0) {

    }

    /**
     * 获取指定文件夹下的文件夹数量，不包含子文件夹
     * @param int $dir_id
     * @return int|string
     * @throws \think\Exception
     */
    public function getCount($folder_id=0, $show_del=false, $show_conceal=false) {
        $Obj = Db::name('dirs')->where('pdir_id', $folder_id);
        if(!$show_del) {
            $Obj->where('is_del',0);
        }
        if(!$show_conceal) {
            $Obj->where('is_conceal',0);
        }
        return $Obj->count();
    }

    /**
     * 获取指定文件夹下的文件夹列表，不包含子文件夹
     * @param int $folder_id
     * @param int $page
     * @param int $limit
     * @param bool $isdel 是否查询已经删除的文件夹
     * @return false|\PDOStatement|string|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getList($folder_id=0, $page=1, $limit=50, $isdel=false, $is_conceal=false) {
        $isdel = $isdel ? 1 : 0;
        $is_conceal = $is_conceal ? 1 : 0;
        $OBJ = Db::name('dirs')->where('pdir_id', $folder_id)->where('is_del',$isdel)->where('is_conceal',$is_conceal)->page($page)->limit($limit);

        if($isdel) {
            $OBJ->where('is_del', 1)->order('del_time desc');
        } else {
            $OBJ->order('dir_mtime desc');
        }
        $datas = $OBJ->select();

        foreach ($datas as &$data) {
            unset($data['client_ipaddr']);
            unset($data['uid']);
            $data['id'] = $data['dirid'];
            $data['type'] = 'dir';
        }

        return $datas;
    }

    public function getById($folder_id=0) {
        $OBJ = Db::name('dirs')->where('uid', $this->UID);
        if($folder_id == 0) {
            $OBJ->where('pdir_id',0);
        } else {
            $OBJ->where('id',$folder_id);
        }
        return $OBJ->find();
    }

    public function getByName($folder_name='/') {
        return Db::name('dirs')->where('dir_name',$folder_name)->where('uid', $this->UID)->find();
    }


    public function rename($Folder_id=0,$new_name='') {
        if(Db::name('dirs')->where('uid',$this->UID)->where('id',$Folder_id)->find()) {
            if(Db::name('dirs')->where('id',$Folder_id)->update(['dir_name'=>$new_name])) {
                success('保存成功');
            }else{
                error('保存失败',500);
            }
        } else {
            error('文件夹不存在',404);
        }
    }

    public function getPdirs($id) {
        $dir = $this->getById($id);
        $ppdirId = explode(',',$dir['ppdir_id']);
        array_splice($ppdirId,0,1);
        $ppdirId = implode(',',$ppdirId);
        return Db::name('dirs')->where('id','in', $ppdirId)->field('id,dir_name')->select();
    }
}